#pragma once

#include "dynamic/object_registry.h"

template < class T, class Key = std::string >
/**
 * @brief FactoryHolder holds a factory object of a specific type
 *
 */
class FactoryHolder
{
public:
    /**
     * @brief
     *
     */
#if 1
    typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry;
#endif
    /**
     * @brief
     *
     */
#if 0
    typedef MaNGOS::Singleton<FactoryHolderRegistry > FactoryHolderRepository;
#endif

    /**
     * @brief
     *
     * @param k
     */
    FactoryHolder(Key k) : i_key(k) {}
    /**
     * @brief
     *
     */
    virtual ~FactoryHolder() {}
    /**
     * @brief
     *
     * @return Key
     */
    inline Key key() const { return i_key; }

    /**
     * @brief
     *
     */
    void RegisterSelf(void) 
    { 
#if 0
        FactoryHolderRepository::Instance().InsertItem(this, i_key); 
#endif
    }
    /**
     * @brief
     *
     */
    void DeregisterSelf(void) 
    { 
#if 0
        FactoryHolderRepository::Instance().RemoveItem(this, false); 
#endif
    }

    /**
     * @brief Abstract Factory create method
     *
     * @param data
     * @return T
     */
    virtual T* Create(void* data = NULL) const = 0;
private:
    Key i_key; /**< TODO */
};

template<class T>
/**
 * @brief Permissible is a classic way of letting the object decide whether how good they handle things.
 *
 * This is not retricted to factory selectors.
 */
class Permissible
{
public:
    /**
     * @brief
     *
     */
    virtual ~Permissible() {}
    /**
     * @brief
     *
     * @param
     * @return int
     */
    virtual int Permit(const T*) const = 0;
};